package com.aier.user.action.pay.tenpay;



import java.io.IOException;
import java.io.PrintWriter;

import javax.annotation.Resource;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.aier.common.common.Constant;
import com.aier.user.action.UserBaseAction;
import com.aier.user.action.pay.tenpay.client.ClientResponseHandler;
import com.aier.user.action.pay.tenpay.client.TenpayHttpClient;
import com.aier.user.action.pay.tenpay.util.TenpayUtil;
import com.aier.user.entity.userapp.Bill;
import com.aier.user.entity.userapp.Commidity;
import com.aier.user.service.IUserBuyService;

@Scope("prototype")
@Component("userTenpayAction")
public class UserTenpayAction extends UserBaseAction {

    private static final long serialVersionUID = 1L;
    
    
    @Resource(name = "userBuyService")
    private IUserBuyService userBuyService;

    private int s;
    // 订单id
    private Long bill_id;
    
    
    @Override
    public String execute() {
        return SUCCESS;
    }

    /**
     * 接收前台页面返回结果
     * @return
     * @throws Exception 
     */    
    public String TenpayReturnReceiver(){
        //---------------------------------------------------------
        //财付通支付应答（处理回调）示例，商户按照此文档进行开发即可
        //---------------------------------------------------------
        
        //创建支付应答对象
        ResponseHandler resHandler = new ResponseHandler(request, response);
        resHandler.setKey(TenpayConfig.SIGN_KEY);
   
        System.out.println("前台回调返回参数:"+resHandler.getAllParameters());
        PrintWriter out = null;
        try {
            out = response.getWriter();
            //判断签名
            if(resHandler.isTenpaySign()) {
                //通知id
                String notify_id = resHandler.getParameter("notify_id");
                //商户订单号
                String out_trade_no = resHandler.getParameter("out_trade_no");
                //财付通订单号
                String transaction_id = resHandler.getParameter("transaction_id");
                //金额,以分为单位
                String total_fee = resHandler.getParameter("total_fee");
                //如果有使用折扣券，discount有值，total_fee+discount=原请求的total_fee
                String discount = resHandler.getParameter("discount");
                //支付结果
                String trade_state = resHandler.getParameter("trade_state");
                //交易模式，1即时到账，2中介担保
                String trade_mode = resHandler.getParameter("trade_mode");
                
                if("1".equals(trade_mode)){       //即时到账 
                    if( "0".equals(trade_state)){
                        //------------------------------
                        //即时到账处理业务开始
                        //------------------------------
                        userBuyService.updateBuyServiceSuccess(Long.valueOf(out_trade_no));
            
                        //注意交易单不要重复处理
                        //注意判断返回金额
                        
                        //------------------------------
                        //即时到账处理业务完毕
                        //------------------------------
    
//                        out.println("即时到帐付款成功");
                        System.out.println("即时到帐付款成功");
                        this.response.sendRedirect(aier_url+"user/pay_completeOrders.shtml");
                    }else{
                        userBuyService.updateBuyServiceFail(Long.valueOf(out_trade_no));
//                        out.println("即时到帐付款失败");
                        System.out.println("即时到帐付款失败");
                        this.response.sendRedirect(aier_url+"user/pay_completeOrders.shtml");
                    }
                }
            } else {
                out.println("认证签名失败");
            }
            out.flush();
            out.close();            
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        //获取debug信息,建议把debug信息写入日志，方便定位问题
        String debuginfo = resHandler.getDebugInfo();
        System.out.println("debuginfo:" + debuginfo);

        return SUCCESS;
    }
    
    /**
     * 接收通知并处理 异步通知
     * @return
     * @throws Exception 
     */
    public String TenpayNotifyReceiver() throws Exception{
        //---------------------------------------------------------
        //财付通支付通知（后台通知）示例，商户按照此文档进行开发即可
        //---------------------------------------------------------

        //创建支付应答对象
        ResponseHandler resHandler = new ResponseHandler(request, response);
        resHandler.setKey(TenpayConfig.SIGN_KEY);

        System.out.println("后台回调返回参数:"+resHandler.getAllParameters());

        //判断签名
        if(resHandler.isTenpaySign()) {
            //通知id
            String notify_id = resHandler.getParameter("notify_id");
            //创建请求对象
            RequestHandler queryReq = new RequestHandler(null, null);
            //通信对象 
            TenpayHttpClient httpClient = new TenpayHttpClient();
            //应答对象
            ClientResponseHandler queryRes = new ClientResponseHandler();
            
            //通过通知ID查询，确保通知来至财付通
            queryReq.init();
            queryReq.setKey(TenpayConfig.SIGN_KEY);
            queryReq.setGateUrl("https://gw.tenpay.com/gateway/simpleverifynotifyid.xml");
            queryReq.setParameter("partner", TenpayConfig.PARTNER);
            queryReq.setParameter("notify_id", notify_id);
            
            //通信对象
            httpClient.setTimeOut(Constant.num_5);
            //设置请求内容
            httpClient.setReqContent(queryReq.getRequestURL());
            System.out.println("验证ID请求字符串:" + queryReq.getRequestURL());
            
            //后台调用
            if(httpClient.call()) {
                //设置结果参数
                queryRes.setContent(httpClient.getResContent());
                System.out.println("验证ID返回字符串:" + httpClient.getResContent());
                queryRes.setKey(TenpayConfig.SIGN_KEY);
                    
                    
                //获取id验证返回状态码，0表示此通知id是财付通发起
                String retcode = queryRes.getParameter("retcode");
                //商户订单号
                String out_trade_no = resHandler.getParameter("out_trade_no");
                //财付通订单号
                String transaction_id = resHandler.getParameter("transaction_id");
                //金额,以分为单位
                String total_fee = resHandler.getParameter("total_fee");
                //如果有使用折扣券，discount有值，total_fee+discount=原请求的total_fee
                String discount = resHandler.getParameter("discount");
                //支付结果
                String trade_state = resHandler.getParameter("trade_state");
                //交易模式，1即时到账，2中介担保
                String trade_mode = resHandler.getParameter("trade_mode");
                    
                //判断签名及结果
                if(queryRes.isTenpaySign()&& "0".equals(retcode)){ 
                    System.out.println("id验证成功");
                    if("1".equals(trade_mode)){       //即时到账 
                        if( "0".equals(trade_state)){
                            //------------------------------
                            //即时到账处理业务开始
                            //------------------------------
                            userBuyService.updateBuyServiceSuccess(Long.valueOf(out_trade_no));
                            //处理数据库逻辑
                            //注意交易单不要重复处理
                            //注意判断返回金额
                            
                            //------------------------------
                            //即时到账处理业务完毕
                            //------------------------------
                            
                            System.out.println("即时到账支付成功");
                            //给财付通系统发送成功信息，财付通系统收到此结果后不再进行后续通知
                            resHandler.sendToCFT("success");
                            
                        }else{
                            userBuyService.updateBuyServiceFail(Long.valueOf(out_trade_no));
                            System.out.println("即时到账支付失败");
                            resHandler.sendToCFT("fail");
                        }
                    }
                }else{
                    //错误时，返回结果未签名，记录retcode、retmsg看失败详情。
                    System.out.println("查询验证签名失败或id验证失败"+",retcode:" + queryRes.getParameter("retcode"));
                }
            } else {
                System.out.println("后台调用通信失败");
                System.out.println(httpClient.getResponseCode());
                System.out.println(httpClient.getErrInfo());
                //有可能因为网络原因，请求已经处理，但未收到应答。
            }
        }else{
            System.out.println("通知签名验证失败");
        }
        
        
        return SUCCESS;
    }

    
    /**
     * 向财付通发送支付请求
     * 
     * @return
     * 
     */
    public String GoTenpay(){
        Bill bill = userBuyService.searchBillById(bill_id);
        Commidity commidity = userBuyService.searchCommidity(bill.getCid());

        //获取商品金额,以分为单位
        int fee = bill.getMoney()*Constant.num_100;
        //商品描述
        String desc = "商品：" + commidity.getCname().trim()+",备注："+commidity.getDescription().trim();
        //获取提交的订单号
        String out_trade_no = bill_id + "";  
        //支付方式
        String trade_mode = "1"; 
        String currTime = TenpayUtil.getCurrTime();
        
        //创建支付请求对象
        RequestHandler reqHandler = new RequestHandler(request, response);
        reqHandler.init();
        //设置密钥
        reqHandler.setKey(TenpayConfig.SIGN_KEY);
        //设置支付网关
        reqHandler.setGateUrl(TenpayConfig.GATEURL);

        String notify_url = aier_url+"userjs/userTenpay_TenpayNotifyReceiver.shtml";
        String return_url = aier_url+"userjs/userTenpay_TenpayReturnReceiver.shtml";
        //-----------------------------
        //设置支付参数
        //-----------------------------
        reqHandler.setParameter("partner", TenpayConfig.PARTNER);    //商户号
        reqHandler.setParameter("out_trade_no", out_trade_no);        //商家订单号
        reqHandler.setParameter("total_fee", String.valueOf(fee));    //商品金额,以分为单位
        reqHandler.setParameter("return_url", return_url);            //交易完成后跳转的URL
        reqHandler.setParameter("notify_url", notify_url);            //接收财付通通知的URL 
        reqHandler.setParameter("body", desc);                        //商品描述
        reqHandler.setParameter("bank_type", "DEFAULT");            //银行类型(中介担保时此参数无效)
        reqHandler.setParameter("spbill_create_ip",request.getRemoteAddr());   //用户的公网ip，不是商户服务器IP
        reqHandler.setParameter("fee_type", "1");                    //币种，1人民币
        reqHandler.setParameter("subject", commidity.getCname().trim());                      //商品名称(中介交易时必填)

        //系统可选参数
        reqHandler.setParameter("sign_type", "MD5");                //签名类型,默认：MD5
        reqHandler.setParameter("service_version", "1.0");            //版本号，默认为1.0
        reqHandler.setParameter("input_charset", "UTF-8");          //字符编码
        reqHandler.setParameter("sign_key_index", "1");             //密钥序号

        //业务可选参数
        reqHandler.setParameter("attach", "");                      //附加数据，原样返回
        reqHandler.setParameter("product_fee", "");                 //商品费用，必须保证transport_fee + product_fee=total_fee
        reqHandler.setParameter("transport_fee", "0");               //物流费用，必须保证transport_fee + product_fee=total_fee
        reqHandler.setParameter("time_start", currTime);            //订单生成时间，格式为yyyymmddhhmmss
        reqHandler.setParameter("time_expire", "");                 //订单失效时间，格式为yyyymmddhhmmss
        reqHandler.setParameter("buyer_id", "");                    //买方财付通账号
        reqHandler.setParameter("goods_tag", "");                   //商品标记
        reqHandler.setParameter("trade_mode", trade_mode);          //交易模式，1即时到账(默认)，2中介担保，3后台选择（买家进支付中心列表选择）
        reqHandler.setParameter("transport_desc", "");              //物流说明
        reqHandler.setParameter("trans_type", "2");                  //交易类型，1实物交易，2虚拟交易
        reqHandler.setParameter("agentid", "");                     //平台ID
        reqHandler.setParameter("agent_type", "");                  //代理模式，0无代理(默认)，1表示卡易售模式，2表示网店模式
        reqHandler.setParameter("seller_id", "");                   //卖家商户号，为空则等同于partner

        //请求的url
        try {
            String requestUrl = reqHandler.getRequestURL();
            //获取debug信息,建议把请求和debug信息写入日志，方便定位问题
            String debuginfo = reqHandler.getDebugInfo();
            System.out.println("requestUrl:  " + requestUrl);
            System.out.println("sign_String:  " + debuginfo);
            reqHandler.doSend();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }
    
    

    
    
    public void setUserBuyService(IUserBuyService userBuyService) {
        this.userBuyService = userBuyService;
    }


    public int getS() {
        return s;
    }


    public void setBill_id(Long bill_id) {
        this.bill_id = bill_id;
    }

    public Long getBill_id() {
        return bill_id;
    }


}
